using SheLife.Domain.Entities;

namespace SheLife.Domain.Interfaces.Repositories
{
    public interface IGrowthGoalRepository : IRepository<GrowthGoal>
    {
        Task<IEnumerable<GrowthGoal>> GetByUserIdAsync(Guid userId);
        Task<IEnumerable<GrowthGoal>> GetByCategoryAsync(string category);
        Task<IEnumerable<GrowthGoal>> GetByStatusAsync(string status);
        Task<IEnumerable<GrowthGoal>> GetByUserIdAndCategoryAsync(Guid userId, string category);
    }

    public interface IGrowthGoalRecordRepository : IRepository<GrowthGoalRecord>
    {
        Task<IEnumerable<GrowthGoalRecord>> GetByGoalIdAsync(Guid goalId);
        Task<IEnumerable<GrowthGoalRecord>> GetByUserIdAndDateRangeAsync(Guid userId, DateTime startDate, DateTime endDate);
        Task<GrowthGoalRecord> GetLatestByGoalIdAsync(Guid goalId);
    }

    public interface IGrowthGoalTaskRecordRepository : IRepository<GrowthGoalTaskRecord>
    {
        Task<IEnumerable<GrowthGoalTaskRecord>> GetByTaskIdAsync(Guid taskId);
        Task<IEnumerable<GrowthGoalTaskRecord>> GetByUserIdAndDateRangeAsync(Guid userId, DateTime startDate, DateTime endDate);
        Task<GrowthGoalTaskRecord> GetLatestByTaskIdAsync(Guid taskId);
    }

    public interface IGrowthArchiveRepository : IRepository<GrowthArchive>
    {
        Task<IEnumerable<GrowthArchive>> GetByUserIdAsync(Guid userId);
        Task<IEnumerable<GrowthArchive>> GetByCategoryAsync(string category);
        Task<IEnumerable<GrowthArchive>> GetByUserIdAndCategoryAsync(Guid userId, string category);
        Task<GrowthArchive> GetLatestByUserIdAsync(Guid userId);
    }

    public interface IGrowthArchiveItemRepository : IRepository<GrowthArchiveItem>
    {
        Task<IEnumerable<GrowthArchiveItem>> GetByArchiveIdAsync(Guid archiveId);
        Task<IEnumerable<GrowthArchiveItem>> GetByUserIdAsync(Guid userId);
        Task<IEnumerable<GrowthArchiveItem>> GetByTypeAsync(string type);
    }

    public interface IEmotionDiaryRepository : IRepository<EmotionDiary>
    {
        Task<IEnumerable<EmotionDiary>> GetByUserIdAsync(Guid userId);
        Task<IEnumerable<EmotionDiary>> GetByUserIdAndDateRangeAsync(Guid userId, DateTime startDate, DateTime endDate);
        Task<IEnumerable<EmotionDiary>> GetByEmotionTypeAsync(string emotionType);
        Task<EmotionDiary> GetLatestByUserIdAsync(Guid userId);
    }

    public interface IEmotionDiaryCommentRepository : IRepository<EmotionDiaryComment>
    {
        Task<IEnumerable<EmotionDiaryComment>> GetByDiaryIdAsync(Guid diaryId);
        Task<IEnumerable<EmotionDiaryComment>> GetByUserIdAsync(Guid userId);
    }

    public interface IEmotionDiaryLikeRepository : IRepository<EmotionDiaryLike>
    {
        Task<IEnumerable<EmotionDiaryLike>> GetByDiaryIdAsync(Guid diaryId);
        Task<IEnumerable<EmotionDiaryLike>> GetByUserIdAsync(Guid userId);
        Task<bool> IsUserLikedAsync(Guid userId, Guid diaryId);
    }

    public interface IGrowthCourseRepository : IRepository<GrowthCourse>
    {
        Task<IEnumerable<GrowthCourse>> GetByCategoryAsync(string category);
        Task<IEnumerable<GrowthCourse>> GetByDifficultyAsync(string difficulty);
        Task<IEnumerable<GrowthCourse>> GetByInstructorAsync(string instructor);
        Task<IEnumerable<GrowthCourse>> SearchByNameAsync(string keyword);
    }

    public interface IGrowthCourseLessonRepository : IRepository<GrowthCourseLesson>
    {
        Task<IEnumerable<GrowthCourseLesson>> GetByCourseIdAsync(Guid courseId);
        Task<IEnumerable<GrowthCourseLesson>> GetByCourseIdOrderByOrderAsync(Guid courseId);
    }

    public interface IUserGrowthCourseRepository : IRepository<UserGrowthCourse>
    {
        Task<IEnumerable<UserGrowthCourse>> GetByUserIdAsync(Guid userId);
        Task<IEnumerable<UserGrowthCourse>> GetByCourseIdAsync(Guid courseId);
        Task<bool> IsUserCourseExistsAsync(Guid userId, Guid courseId);
    }

    public interface IUserGrowthCourseProgressRepository : IRepository<UserGrowthCourseProgress>
    {
        Task<IEnumerable<UserGrowthCourseProgress>> GetByUserIdAndCourseIdAsync(Guid userId, Guid courseId);
        Task<UserGrowthCourseProgress> GetByUserIdAndLessonIdAsync(Guid userId, Guid lessonId);
        Task<IEnumerable<UserGrowthCourseProgress>> GetByUserIdAsync(Guid userId);
    }

    public interface IGrowthCourseReviewRepository : IRepository<GrowthCourseReview>
    {
        Task<IEnumerable<GrowthCourseReview>> GetByCourseIdAsync(Guid courseId);
        Task<IEnumerable<GrowthCourseReview>> GetByUserIdAsync(Guid userId);
        Task<double> GetAverageRatingByCourseIdAsync(Guid courseId);
    }

    public interface IGrowthMilestoneRepository : IRepository<GrowthMilestone>
    {
        Task<IEnumerable<GrowthMilestone>> GetByUserIdAsync(Guid userId);
        Task<IEnumerable<GrowthMilestone>> GetByGoalIdAsync(Guid goalId);
        Task<IEnumerable<GrowthMilestone>> GetByUserIdAndDateRangeAsync(Guid userId, DateTime startDate, DateTime endDate);
        Task<IEnumerable<GrowthMilestone>> GetByUserIdAndStatusAsync(Guid userId, string status);
        Task<IEnumerable<GrowthMilestone>> GetUpcomingMilestonesByUserIdAsync(Guid userId, int days = 30);
        Task<IEnumerable<GrowthMilestone>> GetCompletedMilestonesByUserIdAsync(Guid userId);
    }

    public interface IGrowthRecordRepository : IRepository<GrowthRecord>
    {
        Task<IEnumerable<GrowthRecord>> GetByUserIdAsync(Guid userId);
        Task<IEnumerable<GrowthRecord>> GetByUserIdAndDateRangeAsync(Guid userId, DateTime startDate, DateTime endDate);
        Task<IEnumerable<GrowthRecord>> GetByUserIdAndDateAsync(Guid userId, DateTime date);
        Task<IEnumerable<GrowthRecord>> GetByUserIdAndCategoryAsync(Guid userId, string category);
        Task<GrowthRecord?> GetByUserIdAndDateAndCategoryAsync(Guid userId, DateTime date, string category);
        Task<Dictionary<string, object>> GetMonthlyStatisticsByUserIdAsync(Guid userId, int year, int month);
    }
}